package com.csx.base.concurrency.atomic;

import com.csx.base.concurrency.util.TimeUtil;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * <p> what does this class do ? </p>
 *   该案例是原子数组类的使用
 *   描述:
 *     本案例以一个长度为10的数组作为原子更新对象
 *     启动10个线程同时对该数组中每个坐标位置累增100次,
 *     从而测试数组更新的原子性
 * <p> How does it work ?</p>
 * <p> Why does it do this ?</p>
 *
 * @author cuisongxu
 * @date 2024/12/3 周二 9:26
 */
public class AtomicIntegerArrayTest {

    private final AtomicIntegerArray atomicArr = new AtomicIntegerArray(10);

    private final ExecutorService executorService = new ThreadPoolExecutor(
            5,
            10,
            300,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(100),
            new ThreadPoolExecutor.AbortPolicy()
    );

    // 入口方法
    public void test() {
        // 提交10个自增任务到线程池,每个任务为每个数组中元素自增100次,也就是最终数组中每个元素值为1000
        for (int i = 0; i < 10; i++) {
            executorService.submit(new AtomicArrIncrement());
        }
        // 等待线程执行完毕
        executorService.shutdown();
        while (!executorService.isTerminated()) {
            try {
                TimeUnit.MILLISECONDS.sleep(20);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        System.out.println("原子数组: " + atomicArr);

    }

    class AtomicArrIncrement implements Runnable {
        @Override
        public void run() {
            // 平均数组中的每个元素自增100次
            for (int i = 0; i < 1000; i++) {
                atomicArr.incrementAndGet(i % atomicArr.length());
            }
        }
    }

    public static void main(String[] args) {
        AtomicIntegerArrayTest atomicIntegerArrayTest = new AtomicIntegerArrayTest();
        atomicIntegerArrayTest.test();
    }
}
